<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <meta http-equiv="x-ua-compatible" content="ie=9">
    <meta http-equiv="MSThemeCompatible" content="yes">
    <title>Timer</title>
    <hta:application
      ApplicationName="Example"
      MaximizeButton="no"
      Border="dialog"
      Scroll="no"
      Icon="sw.ico"
    >
    <style>
      body{
        margin: 0;
        padding: 10px;
        font-family: "Microsoft Yahei", SimHei;
      }
      button{
        height: 32px;
        width: 120px;
        padding: 0;
      }
      .wrap0{
        overflow: hidden;
        margin-bottom: 10px;
      }
      .wrap0>.timer,
      .wrap0>.btns{
        float: left;
        height: 108px;
      }
      .wrap0>.timer{
        text-align: center;
        width: 400px;
        margin-right: 10px;
        font-size: 0px;
      }
      .wrap0>.timer>*{
        display: inline-block;
        vertical-align: top;
      }
      .wrap0>.timer>.num{
        font-size: 108px;
        font-family: "Courier New", Courier, monospace;
      }
      .wrap0>.timer>.split{
        width: 50px;
        height: 108px;
        position: relative;
      }
      .wrap0>.timer>.split>.dot{
        width: 10px;
        height: 10px;
        position: absolute;
        left: 20px;
        background: black;
      }
      .wrap0>.timer>.split>.d0{
        top: 35px;
      }
      .wrap0>.timer>.split>.d1{
        top: 65px;
      }
      .wrap0>.btns>button{
        display: block;
        margin-bottom: 6px;
      }
      .wrap1{
        text-align: right;
        margin-bottom: 10px;
      }
      .wrap1>.num{
        font-family: consolas;
      }
      .table{
        font-size: 0;
      }
      .table .td{
        line-height: 32px;
        display: inline-block;
        font-size: 16px;
        width: 130px;
        text-align: center;
      }
      .table .td.t3{
        width: 100px;
      }
      .table .td.t4{
        width: 500px;
        line-height: 164px;
      }
      .table>.tr:nth-child(odd){
        background: #eee;
      }
      .table>.tr.nodata{
        display: block;
      }
      .table button{
        border: none;
        background: transparent;
        width: auto;
        cursor: pointer;
        text-decoration: underline;
        color: blue;
      }
      .wrap2{
        border: 1px solid #ccc;
      }
      .wrap3{
        height: 164px;
        overflow: auto;
        border: 1px solid #ccc;
        border-top: 0;
      }
    </style>
  </head>
  <script>

    window.resizeTo(570, 420)

    var timeT, dotT
    var timer = 0
    var WORKING = 0, IDLE = 1
    var FREE_TIMER = 0, FQ_TIMER = 1
    var fqstate
    var timeS, timeE

    var shell = new ActiveXObject('WScript.Shell')
    var storageFile = shell.ExpandEnvironmentStrings('%LOCALAPPDATA%') + '\\.timer-storage.json'
    var fso = new ActiveXObject('Scripting.FileSystemObject')
    var storage

    function init(){
      window.timer_min = document.getElementById('timer_min')
      window.timer_sec = document.getElementById('timer_sec')
      window.timer_dot = document.getElementById('timer_dot')
      window.log_table = document.getElementById('log_table')
      window.log_table_nodata = document.getElementById('log_table_nodata')
      var tableline = document.getElementById('tableline-template').innerText
      window.tpl_tableline = parseTpl(tableline)
      if (fso.FileExists(storageFile)) {
        var fp = fso.OpenTextFile(storageFile, 1)
        storage = JSON.parse(fp.ReadAll())
        fp.Close()
        var today = storage[getNowDate()]
        if(today && today.length){
          log_table_nodata.style.display = 'none'
          today.forEach(function(el){
            log_table.insertAdjacentHTML('beforeend', tpl_tableline(el))
          })
          updateTotal()
        }
      }
    }

    function parseTpl(str) {
      return function(o){
        return str.replace(/{{(.+?)}}/g,  function(m, n){
          return o[n]
        })
      }
    }

    function getTimeString(t){
      return t.getHours() + '时' + t.getMinutes() + '分'
    }

    function getRangeString() {
      var min = parseInt(timer / 60)
      var hour = parseInt(min / 60)
      var out = ''
      hour && (out += hour + '时')
      out += min % 60 + '分'
      return out
    }

    function addTableLine(t0, t1){
      log_table_nodata.style.display = 'none'
      log_table.insertAdjacentHTML('beforeend', tpl_tableline({
        start: getTimeString(t0),
        end: getTimeString(t1),
        min: parseInt(timer / 60),
        range: getRangeString()
      }))
      updateTotal()
    }

    function delTableLine(el){
      var line = el.parentNode.parentNode
      log_table.removeChild(line)
      if(!log_table.getElementsByClassName('data').length){
        log_table_nodata.style.display = 'block'
      }
      updateTotal()
    }

    function updateTotal(){
      var datas = log_table.getElementsByClassName('data')
      datas = Array.prototype.slice.call(datas)
      var totalmin = datas.reduce(function(acc, el){
        return acc + parseInt(el.getAttribute('data-min'))
      }, 0)
      var hour = parseInt(totalmin / 60)
      var min = totalmin % 60
      document.getElementById('total_hour').innerText = hour
      document.getElementById('total_min').innerText = min
    }
    
    function updateTimer(){
      var min = parseInt(timer / 60)
      var sec = timer % 60
      timer_min.innerText = min < 10 ? '0' + min : min
      timer_sec.innerText = sec < 10 ? '0' + sec : sec
      if (timer == 90 * 60) {
        addTableLine(timeS, new Date())
        timer = 0
        timeS = new Date()
      }
    }

    function dotInterval(){
      timer_dot.style.opacity = 1
      dotT = setTimeout(function(){
        timer_dot.style.opacity = 0
        dotT = setTimeout(dotInterval, 400)
      }, 600)
    }

    function playSound(){
      document.embeds['notify'].play()
      setTimeout(function(){
        document.embeds['notify'].stop()
      }, 12 * 1000)
    }

    function startTimer(type){
      if(timeT) return
      dotInterval()
      fqstate = WORKING
      timeS = new Date()
      timeT = setInterval(function(){
        if (type == FQ_TIMER && fqstate == WORKING && timer == 60 * 25) {
          fqstate = IDLE
          addTableLine(timeS, new Date())
          timer = 0
          playSound()
        }else if (type == FQ_TIMER && fqstate == IDLE && timer == 60 * 5) {
          fqstate = WORKING
          timer = 0
          timeS = new Date()
          playSound()
        }else{
          updateTimer()
          timer++
        }
      }, 1000)
    }

    function stopTimer(){
      if(!timer) return
      clearInterval(timeT)
      timeT = null
      clearTimeout(dotT)
      timer_dot.style.opacity = 1
      timeE = new Date()
      if (timeE.getTime() - timeS.getTime() > 60 * 1000) {
        addTableLine(timeS, timeE)
      }
      timer = 0
    }

    function getNowDate(){
      var now = new Date()
      return now.getFullYear() + '.' + (now.getMonth() + 1) + '.' + now.getDate()
    }

    function exit(){
      var out = {}
      var dom_nds = log_table.getElementsByClassName('data')
      dom_arr = Array.prototype.slice.call(dom_nds)
      out[getNowDate()] = dom_arr.map(function(el){
        return {
          start: el.getElementsByClassName('t0')[0].innerText,
          end: el.getElementsByClassName('t1')[0].innerText,
          range: el.getElementsByClassName('t2')[0].innerText,
          min: el.getAttribute('data-min')
        }
      })
      var fp = fso.OpenTextFile(storageFile, 2, true)
      fp.Write(JSON.stringify(out))
      fp.Close()
    }
  </script>
  <body onload="init()" onbeforeunload="exit()">
    <div class="wrap0">
      <div class="timer">
        <div class="num" id="timer_min">00</div>
        <div class="split" id="timer_dot">
          <div class="dot d0"></div>
          <div class="dot d1"></div>
        </div>
        <div class="num" id="timer_sec">00</div>
      </div>
      <div class="btns">
        <button onclick="startTimer(FREE_TIMER)">开始自由计时</button>
        <button onclick="startTimer(FQ_TIMER)">开始番茄计时</button>
        <button onclick="stopTimer()">停止计时</button>
      </div>
    </div>
    <div class="wrap1">
      今日学习时间总计：
      <span class="num" id="total_hour">0</span> 小时
      <span class="num" id="total_min">0</span> 分钟
    </div>
    <div class="wrap2 table thead">
      <div class="td t0">开始时间</div>
      <div class="td t1">结束时间</div>
      <div class="td t2">有效时间</div>
      <div class="td t3">操作</div>
    </div>
    <div class="wrap3 table" id="log_table">
      <div class="tr nodata" id="log_table_nodata">
        <div class="td t4">暂无数据</div>
      </div>
    </div>
    <script id="tableline-template" type="text/x-handlebars-template">
      <div class="tr data" data-min="{{min}}">
        <div class="td t0">{{start}}</div>
        <div class="td t1">{{end}}</div>
        <div class="td t2">{{range}}</div>
        <div class="td t3"><button onclick="delTableLine(this)">删除</button></div>
      </div>
    </script>
    <embed name="notify" style="display: none;" src="C:\Windows\Media\notify.wav" loop="true" hidden="true" autostart="false">
  </body>
</html>
